package com.android.mapexample;

import java.util.ArrayList;

import android.app.ActionBar;
import android.app.Dialog;
import android.graphics.Color;
import android.location.Location;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;

import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMap.OnMapClickListener;
import com.google.android.gms.maps.GoogleMap.OnMapLongClickListener;
import com.google.android.gms.maps.GoogleMap.OnMarkerClickListener;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.maps.model.Polygon;
import com.google.android.gms.maps.model.PolygonOptions;
import com.google.gson.Gson;
import com.mapexample.database.MySQLiteHelper;
import com.mapexample.utilities.Coordinates;
import com.mapexample.utilities.Utility;


/**
 * The Class MainActivity.
 */
public class MainActivity extends FragmentActivity implements
		OnMapLongClickListener, OnMapClickListener, OnMarkerClickListener
{

	/** The tag. */
	String TAG = "MainActivity";

	/** The g map. */
	private GoogleMap gMap;

	/** The polygon options. */
	PolygonOptions polygonOptions;

	/** The polygon. */
	Polygon polygon;

	/** The location. */
	Location location;

	/** The marker clicked. */
	boolean markerClicked;

	/** The action bar. */
	ActionBar actionBar;
	
	/** The db. */
	MySQLiteHelper db;

	/** The multipolygon. */
	String MULTIPOLYGON = "Multipolygon";

	/** The feature. */
	PolygonFeature feature;

	/** The a list1. */
	ArrayList<Double> aList1;

	/** The a list2. */
	ArrayList<ArrayList<Double>> aList2;

	/** The a list3. */
	ArrayList<ArrayList<ArrayList<Double>>> aList3;

	/** The main array list. */
	ArrayList<ArrayList<ArrayList<ArrayList<Double>>>> mainArrayList;

	/** The cord. */
	Coordinates cord;

	/*
	 * Overridden method onCreate
	 * 
	 * @param savedInstanceState
	 */
	@Override
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		initializeObjects();

		try
		{
			if (Utility.isOnline(MainActivity.this))
			{
				initializeMap();

				gMap.setMyLocationEnabled(true);

				gMap.setOnMapClickListener(this);
				gMap.setOnMapLongClickListener(this);
				gMap.setOnMarkerClickListener(this);

				markerClicked = false;
			}
			else
			{
				Log.i(TAG, "Network not available.");
				showDialog(0);
			}

		}
		catch (Exception e)
		{
			Log.i(TAG, "Exception while creating maps.");
			e.printStackTrace();
		}

	}

	/**
	 * Initialize objects.
	 */
	public void initializeObjects()
	{
		db = new MySQLiteHelper(MainActivity.this);

		feature = new PolygonFeature();
		mainArrayList = new ArrayList<ArrayList<ArrayList<ArrayList<Double>>>>();

		aList3 = new ArrayList<ArrayList<ArrayList<Double>>>();

		aList2 = new ArrayList<ArrayList<Double>>();

		cord = new Coordinates();

		actionBar = getActionBar();

		actionBar.setDisplayShowTitleEnabled(true);
		actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
	}

	/*
	 * Overridden method onCreateOptionsMenu
	 * 
	 * @param menu
	 * 
	 * @return
	 */
	@Override
	public boolean onCreateOptionsMenu(Menu menu)
	{
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.main, menu);
		return super.onCreateOptionsMenu(menu);

	}

	/*
	 * Overridden method onOptionsItemSelected
	 * 
	 * @param item
	 * 
	 * @return
	 */
	@Override
	public boolean onOptionsItemSelected(MenuItem item)
	{
		switch (item.getItemId())
		{
		case R.id.action_search:
			showToast("Search");
			break;

		case R.id.action_help:
			showToast("Help");
			
			break;

		case R.id.action_settings:
			showToast("Settings");
			break;

		case R.id.action_save:
			try
			{
				savePolyGonList();
			}
			catch (Exception e)
			{
				Log.i(TAG, "Exception while saving polygon.");
				e.printStackTrace();
			}
			break;

		}
		return super.onOptionsItemSelected(item);
	}

	/*
	 * Overridden method onResume
	 */
	@Override
	protected void onResume()
	{
		super.onResume();
		try
		{
			initializeMap();
		}
		catch (Exception e)
		{
			Log.i(TAG, "Exception while creating maps.");
			e.printStackTrace();
		}

	}

	/**
	 * loads Map, if map is not created, it creates for you.
	 */
	private void initializeMap()
	{
		if (gMap == null)
		{
			gMap = ((MapFragment) getFragmentManager().findFragmentById(
					R.id.mapFrag)).getMap();

			if (gMap == null)
			{
				showToast("Sorry! Unable to create Maps.");
			}
		}

	}

	/**
	 * Show toast.
	 * 
	 * @param msg the msg
	 */
	public void showToast(String msg)
	{
		Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_LONG).show();
	}

	/*
	 * Overridden method onMarkerClick
	 * 
	 * @param marker
	 * 
	 * @return
	 */
	@Override
	public boolean onMarkerClick(Marker marker)
	{
		if (markerClicked)
		{

			if (polygon != null)
			{
				polygon.remove();
				polygon = null;
			}

			polygonOptions.add(marker.getPosition());
			polygonOptions.strokeColor(Color.RED);
			polygonOptions.fillColor(Color.BLUE);
			polygon = gMap.addPolygon(polygonOptions);

		}
		else
		{
			if (polygon != null)
			{
				polygon.remove();
				polygon = null;
			}

			polygonOptions = new PolygonOptions().add(marker.getPosition());
			markerClicked = true;
		}
		return true;
	}

	/*
	 * Overridden method onMapClick
	 * 
	 * @param point
	 */
	@Override
	public void onMapClick(LatLng point)
	{
		gMap.animateCamera(CameraUpdateFactory.newLatLng(point));

		markerClicked = false;

	}

	/*
	 * Overridden method onMapLongClick
	 * 
	 * @param point
	 */
	@Override
	public void onMapLongClick(LatLng point)
	{
		aList1 = new ArrayList<Double>();
		gMap.addMarker(new MarkerOptions().position(point).title(
				point.toString()));

		Log.i(TAG, "LatLng: " + point);

		double lati = point.latitude;
		double longi = point.longitude;

		Log.i(TAG, "lati:" + lati);
		Log.i(TAG, "longi:" + longi);

		aList1.add(lati);
		aList1.add(longi);
		aList2.add(aList1);

		markerClicked = false;

	}

	/**
	 * Save poly gon list.
	 */
	public void savePolyGonList()
	{
		Gson gson = new Gson();
		aList3.add(aList2);
		mainArrayList.add(aList3);

		feature.setType(MULTIPOLYGON);
		feature.setCoordinates(mainArrayList);

		String jsonStr = gson.toJson(feature);
		Log.i(TAG, "New JSON Str: " + jsonStr);
		saveToDB(jsonStr);
	}

	/**
	 * Save to db.
	 * 
	 * @param _jsonStr the _json str
	 */
	public void saveToDB(String _jsonStr)
	{
		cord.setLatLongJsonStr(_jsonStr);
		db.addToDatabase(cord);
		showToast("Values added to database.");
		resetObjects();
	}

	/**
	 * Gets the values from db.
	 * 
	 * @return the values from db
	 */
	public void getValuesFromDB()
	{
		db.getValueFromDB();
	}

	public void resetObjects()
	{
		aList1 = new ArrayList<Double>();
		aList2 = new ArrayList<ArrayList<Double>>();
		aList3 = new ArrayList<ArrayList<ArrayList<Double>>>();
		mainArrayList = new ArrayList<ArrayList<ArrayList<ArrayList<Double>>>>() ;
		feature = new PolygonFeature();
	}
	
	/*
	 * Overridden method onCreateDialog
	 * 
	 * @param id
	 * 
	 * @return
	 */
	@Override
	protected Dialog onCreateDialog(int id)
	{
		final Dialog d = new Dialog(MainActivity.this);
		
		Button okBtn;

		d.setContentView(R.layout.dialog_layout);
		d.setCanceledOnTouchOutside(false);
		d.setTitle("MapExample");
		switch (id)
		{
		case 0:
			okBtn = (Button) d.findViewById(R.id.dOkBtn);
			okBtn.setOnClickListener(new OnClickListener()
			{

				@Override
				public void onClick(View v)
				{
					d.dismiss();

				}
			});
			break;
		}

		return d;
	}

}
